# -*- coding: utf-8 -*-
# Created by tubin on 2017/8/11
import datetime
import time
import calendar

START_DATE = '1970-01-01 08:00:00'  # 起始日期
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"  # 时间格式
PER_DAY_SECONDS = 24 * 60 * 60  # 一天的秒数
PER_WEEK_SECONDS = 7 * PER_DAY_SECONDS  # 一周的秒数


def today_remain_seconds():
    """
    今天剩余秒
    :return:
    """
    dt = datetime.datetime.now() + datetime.timedelta(days=1)
    dt = dt.strftime("%Y-%m-%d") + " 00:00:00"
    timeArray = time.strptime(dt, "%Y-%m-%d %H:%M:%S")
    return int(time.mktime(timeArray)) - int(time.time())


def today_str(days=0):
    dt = datetime.datetime.now()
    if days:
        delta = datetime.timedelta(days=days)
        dt = dt + delta
    return dt.strftime('%Y-%m-%d')


def now_str():
    dt = datetime.datetime.now()
    return dt.strftime('%Y-%m-%d %H:%M:%S')


def get_next_time(seconds, minutes=0, hours=0, days=0):
    """
    获取下一个时间戳
    :param seconds:
    :param minutes:
    :param hours:
    :param days:
    :return:
    """
    cur_time = int(time.time())
    next_time = cur_time + seconds
    if minutes:
        next_time += minutes * 60
    if hours:
        next_time += hours * 60 * 60
    if days:
        next_time += days * 60 * 60 * 24
    return next_time


def timestamp_2_datetime_str(timestamp, format=DATE_FORMAT):
    """
    时间戳转换成日期字符串
    :param timestamp:
    :return:
    """
    # 转换成localtime
    time_local = time.localtime(timestamp)
    # 转换成新的时间格式
    return time.strftime(format, time_local)


def datetime_str_2_timestamp(datetime_str, format=DATE_FORMAT):
    """
    日期字符串转换成时间戳
    :param datetime_str:
    :param format:
    :return:
    """
    time_local = datetime.datetime.strptime(datetime_str, format)
    time_local.timestamp()
    return int(time_local.timestamp())


def timestamp_2_datetime(timestamp, to_local=True):
    """
    时间戳转换成日期字符串
    :param timestamp:
    :return:
    """
    if to_local:  # 本地时间
        return datetime.datetime.fromtimestamp(timestamp)
    return datetime.datetime.utcfromtimestamp(timestamp)


def is_over_a_year(start_timestamp=None, end_timestamp=None):
    """
    判断是否相差超过一年
    :param start_timestamp:
    :param end_timestamp:
    :return:
    """
    if not start_timestamp or not end_timestamp or start_timestamp > end_timestamp:
        return True
    d1 = datetime.datetime.fromtimestamp(start_timestamp)
    d2 = datetime.datetime.fromtimestamp(end_timestamp)
    return (d2 - d1).days > 365


def __gen_dates(b_date, days):
    """
    时间累加
    :param b_date:
    :param days:
    :return:
    """
    day = datetime.timedelta(days=1)
    for i in range(days):
        yield b_date + day * i


def __gen_year_month(date, mons):
    """
    月累加
    :param year:
    :param mons:
    :return:
    """
    for i in range(mons):
        yield next_date_with_differ_month(date, i * 1)


def get_days_of_month(year, mon):
    """
    获取一个月中的天数
    :param year:
    :param mon:
    :return:
    """
    return calendar.monthrange(year, mon)[1]


def addzero(n):
    """
    个位数补零
    :param n:
    :return:
    """
    nabs = abs(int(n))
    if nabs < 10:
        return "0" + str(nabs)
    else:
        return str(nabs)


def next_date_with_differ_month(date, n):
    """
    加上n个月后的日期
    :param date:
    :param n:
    :return:
    """
    date = fex_date_time(date)

    year = int(date.strftime("%Y"))
    mon = int(date.strftime("%m"))
    total_mon = mon + n
    if n >= 0:
        if total_mon <= 12:
            return str(year), addzero(total_mon)
        else:
            i = int(total_mon / 12)
            j = int(total_mon % 12)
            if j == 0:
                i -= 1
                j = 12
            year += i
            return str(year), addzero(j)
    else:
        if (total_mon > 0) and (total_mon < 12):
            total_mon = addzero(total_mon)
            return str(year), total_mon
        else:
            i = int(total_mon / 12)
            j = int(total_mon % 12)
            if j == 0:
                i -= 1
                j = 12
                year += i
            return str(year), addzero(j)


def fex_date_time(date_time):
    """
    转换成datetime对象
    :param date_time:
    :return:
    """
    if isinstance(date_time, str):
        return datetime.datetime.strptime(date_time, DATE_FORMAT)
    elif isinstance(date_time, int):
        return datetime.datetime.fromtimestamp(date_time)
    elif isinstance(date_time, datetime.datetime):
        return date_time
    else:
        return None


def month_differ(start=None, end=None):
    """
    相差几个月
    :param start:
    :param end:
    :return:
    """
    if start is None:
        start = datetime.datetime.strptime(START_DATE, DATE_FORMAT)
    else:
        start = fex_date_time(start)
    if end is None:
        end = datetime.datetime.now()
    else:
        end = fex_date_time(end)
    d = abs((end.year - start.year) * 12 + (end.month - start.month) * 1)
    return d


def get_day_list_between_2date(start=None, end=None, format="%Y-%m-%d"):
    """
    获取两个时间之间的天列表
    :param start: 开始日期
    :param end: 结束日期
    :return:
    """
    if not start:
        start = datetime.datetime.strptime(START_DATE, DATE_FORMAT)
    else:
        start = fex_date_time(start)
    if not end:
        end = datetime.datetime.now()
    else:
        end = fex_date_time(end)
    data = []
    for d in __gen_dates(start, (end - start).days):
        data.append(d.strftime(format))
    d = end.strftime(format)
    if data.count(d) == 0:
        data.append(d)
    return data


def get_week_list_between_2date(start=None, end=None, format='%Y-%m-%d'):
    """
    获取两个时间之间的周列表
    :param start:
    :param end:
    :param format:
    :return:
    """
    date1 = fex_date_time(start)
    date2 = fex_date_time(end)
    delta = date2 - date1
    # 秒
    total_seconds = delta.total_seconds()
    # 周
    weeks = total_seconds // PER_WEEK_SECONDS
    # 天
    days = total_seconds // PER_DAY_SECONDS
    if weeks * PER_WEEK_SECONDS < total_seconds:
        weeks += 1

    one_day = datetime.timedelta(days=1)
    # WEEK = ["M", "T", "W", "R", "F", "S", "U"]

    d0 = date1
    weeks = []
    weekdays = [d0, ]
    for i in range(int(days)):
        _w1 = d0.strftime("%Y/%U")
        d0 += one_day
        _w2 = d0.strftime("%Y/%U")
        if _w1 != _w2:
            weeks.append([_w1, str(weekdays[0].strftime(format)), str(weekdays[len(weekdays) - 1].strftime(format))])
            weekdays = []
        weekdays.append(d0)
    weeks.append(
        [weekdays[0].strftime("%Y/%U"), str(weekdays[0].strftime(format)),
         str(weekdays[len(weekdays) - 1].strftime(format))])
    return weeks


def get_month_list_between_2date(start=None, end=None, format="-"):
    """
    获取两个时间之间的月列表
    :param start:
    :param end:
    :param format:
    :return:
    """
    if not start:
        start = datetime.datetime.strptime(START_DATE, DATE_FORMAT)
    else:
        start = fex_date_time(start)
    if not end:
        end = datetime.datetime.now()
    else:
        end = fex_date_time(end)
    mons = month_differ(start, end)
    data = []
    for d in __gen_year_month(start, mons + 1):
        data.append(d[0] + format + d[1])
    return data



    # cur_time = int(time.time())
    # nx_time = get_next_time(0, 0, 0, -30)
    # print(timestamp_2_datetime_str(cur_time))
    # print(timestamp_2_datetime_str(nx_time))
    # print(timestamp_2_datetime(1502260554, True))
    # print(fex_date_time(datetime.datetime.now()))
    # print(month_differ("2017-01-01", "2017-07-02"))
    # print(get_month_list_between_2date("2016-01-01 00:00:00", "2017-05-07 22:12:23"))?\
    # print(timestamp_2_datetime_str(datetime_str_2_timestamp("2017-08-1 16:38:23")))

    # print(get_week_list_between_2date("2016-12-20 00:00:00", "2018-02-13 16:38:23"))
    #
    # a = fex_date_time("2017-1-1 11:07:32")
    # print(a.strftime("%Y/%U"))
    # print(datetime_str_2_timestamp("2017-08-21 16:38:23"))
